package com.sast.user_backend.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sast.user_backend.common.ErrorCode;
import com.sast.user_backend.exception.BusinessException;
import com.sast.user_backend.mapper.UserMapper;
import com.sast.user_backend.model.User;
import com.sast.user_backend.model.UserEditRequest;
import com.sast.user_backend.model.UserRegisterRequest;
import com.sast.user_backend.model.UserVO;
import com.sast.user_backend.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;

import static com.sast.user_backend.constant.UserConstant.USER_LOGIN_STATE;

/**
 * @author 86139
 * @description 针对表【user】的数据库操作Service实现
 * @createDate 2025-07-02 15:42:51
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    // 盐值，混淆密码
    public static final String SALT = "dmj";

    /**
     *
     * @param userRegisterRequest
     * @return
     */
    @Override
    public long register(UserRegisterRequest userRegisterRequest) {
        String account = userRegisterRequest.getAccount();
        String password = userRegisterRequest.getPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();
        // 用户名和密码校验
        if (StringUtils.isAnyBlank(account, password, checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名或密码为空");
        }
        if (account.length() < 2) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短");
        }
        // 密码和校验密码相同
        if (!password.equals(checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
        }
        synchronized (account.intern()) {
            // 账户不能重复
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getAccount, account);
            long count = this.baseMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
            }
            //加密
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + password).getBytes());
            User user = new User();
            BeanUtil.copyProperties(userRegisterRequest,user);
            user.setPassword(encryptPassword);
            user.setCreateTime(new Date());
            user.setIsDelete(0);
            //save
            boolean saveResult = this.save(user);
            if (!saveResult) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败，数据库错误");
            }
            log.info("用户 {} 注册成功", user.getAccount());
            return user.getId();
        }
    }

    /**
     * 用户登录
     *
     * @param account
     * @param password
     * @param request
     * @return
     */
    @Override
    public UserVO login(String account, String password, HttpServletRequest request) {
        // 1. 校验
        if (StringUtils.isAnyBlank(account, password)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        // 密码校验
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + password).getBytes());
        // 查询到该用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAccount, account)
                .eq(User::getPassword, encryptPassword)
                .ne(User::getIsDelete, 1);
        User user = this.baseMapper.selectOne(queryWrapper);
        if (user == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误");
        }
        log.info("用户 {} 登录成功", user.getAccount());
        // 3. 记录用户的登录态
        request.getSession().setAttribute(USER_LOGIN_STATE, user);
        return this.getUserVO(user);
    }

    /**
     *
     * @param userEditRequest
     * @param request
     * @return
     */
    @Override
    public long edit(UserEditRequest userEditRequest,HttpServletRequest request) {
        User user = getLoginUser(request);
        String oldPassword = userEditRequest.getOldPassword();
        String newPassword = userEditRequest.getNewPassword();
        String checkNewPassword = userEditRequest.getCheckNewPassword();
        // 如果是修改密码
        if(!StringUtils.isAllEmpty(oldPassword,newPassword,checkNewPassword)){
            // 旧密码校验
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + oldPassword).getBytes());
            if (!encryptPassword.equals(user.getPassword())) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "旧密码错误");
            }
            // 新密码两次输入相同
            if (!newPassword.equals(checkNewPassword)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
            }
            user.setPassword(DigestUtils.md5DigestAsHex((SALT + newPassword).getBytes()));
        }
        //update
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId,user.getId());
        String newEncryptPassword = DigestUtils.md5DigestAsHex((SALT + newPassword).getBytes());
        updateWrapper.set(StringUtils.isNotBlank(userEditRequest.getNewPassword()),User::getPassword,newEncryptPassword);
        updateWrapper.set(StringUtils.isNotBlank(userEditRequest.getName()),User::getName,userEditRequest.getName());
        updateWrapper.set(StringUtils.isNotBlank(userEditRequest.getPhone()),User::getPhone,userEditRequest.getPhone());
        boolean updateResult = this.update(user,updateWrapper);
        if (!updateResult) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "修改失败，数据库错误");
        }
        log.info("用户 {} 信息修改成功", user.getAccount());

        return user.getId();
    }

    /**
     * 获取当前登录用户     *
     *
     * @param request
     * @return
     */
    @Override
    public User getLoginUser(HttpServletRequest request) {
        // 先判断是否已登录
        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        User currentUser = (User) userObj;
        if (currentUser == null || currentUser.getId() == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        return currentUser;
    }

    /**
     * 是否为管理员
     *
     * @param request
     * @return
     */
    @Override
    public boolean isAdmin(HttpServletRequest request) {
        // 仅管理员可查询
        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        User user = (User) userObj;
        return isAdmin(user);
    }

    @Override
    public boolean isAdmin(User user) {
        return user.getIsAdmin().equals(1);
    }

    /**
     * 用户注销     *
     *
     * @param request
     */
    @Override
    public boolean logout(HttpServletRequest request) {
        if (request.getSession().getAttribute(USER_LOGIN_STATE) == null) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录");
        }
        // 移除登录态
        request.getSession().removeAttribute(USER_LOGIN_STATE);
        return true;
    }

    @Override
    public boolean delete(String userAccount) {
        // 查询到该用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAccount, userAccount);
        User user = this.baseMapper.selectOne(queryWrapper);
        if (user == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "该用户不存在");
        }
        user.setIsDelete(1);
        return true;
    }

    private UserVO getUserVO(User user) {
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        return userVO;
    }
}




